﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using AnaxibiaStudios.Smug;

namespace SmugTest
{
#if DETOUR_ENABLED
  [TestClass]
  public class CoreUseCaseTest
  {
    [TestMethod]
    public void ReturnsTest()
    {
      var airplane = Create.Proxy<Airplane>();

      Prepare.Func<bool>(airplane.DropGear).Returns(true);
      Assert.IsTrue(airplane.Land());

      Prepare.Func<bool>(airplane.DropGear).Returns(false);
      Assert.IsFalse(airplane.Land());
    }

    [TestMethod]
    public void ReplaceWithTest()
    {
      var cat = Create.Proxy<Cat>();

      bool detourUsed = false;
      Prepare.Action(cat.Meow).ReplaceWith(() => detourUsed = true);

      cat.Meow();

      Assert.IsTrue(detourUsed);
    }

    [TestMethod]
    public void CalledOnceTest()
    {
      var airplane = Create.Proxy<Airplane>();

      Prepare.Func<bool>(airplane.DropGear).CalledOnce();

      airplane.Land();

      Verify.AllCallsTo(airplane);
    }

    [TestMethod]
    public void CallTest()
    {
      var airplane = Create.Proxy<Airplane>();

      // default prep.call is CalledAtLeastOnce (thus would be redundant to specify)
      Prepare.Call(() => airplane.DropGear(3)).Returns(true);
  
      Assert.IsTrue(airplane.DropGear(3));

      Verify.AllCallsTo(airplane);
    }

    [TestMethod]
    public void HistoryTest()
    {
      var airplane = Create.Proxy<Airplane>();

      airplane.DropGear();
      airplane.DropGear();
      airplane.DropGear();
      airplane.DropGear();
      airplane.DropGear();

      var history = History.Func<bool>(airplane.DropGear);

      Assert.AreEqual(5, history.CallCount);
    }

    [TestMethod]
    public void HistoryMetaFromPrepareTest()
    {
      var airplace = Create.Proxy<Airplane>();

      var prep = Prepare.Func<bool>(airplace.Land); // defaults to CalledAtLeastOnce

      airplace.Land();

      Assert.AreEqual(1, prep.History.CallCount);
    }

    [TestMethod]
    public void StrictVerificationTest()
    {
      var airplane = Create.Proxy<Airplane>();

      Prepare.Func<bool>(airplane.DropGear);

      airplane.DropGear();

      Verify.AllCallsTo(airplane, ReplayRule.PreparedMethodsOnly);
    }
  }
#endif
}
